package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ConfConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.RecordTable;
import com.ruoyi.system.mapper.RecordManageMapper;
import com.ruoyi.system.mapper.RecordTableMapper;
import com.ruoyi.system.service.IRecordManageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.validation.Validator;
import java.io.File;
import java.util.*;

/**
 * 档案  Service业务层处理
 *
 * @author tangrs
 * @date 2022-10-10
 */
@Service
public class RecordManageServiceImpl implements IRecordManageService {
    @Autowired
    protected Validator validator;
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private RecordManageMapper recordManageMapper;

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RecordTableMapper recordTableMapper;

    @Autowired
    private SysConfigServiceImpl sysConfigService;

    /***
     * 案卷包导出
     * @param id
     * @return
     */
    @Override
    public File selectRecordFileExport(String id, Map<String, Object> mapParam) {
        List<Map<String, Object>> mapList = new ArrayList();
        if ("3".equals(mapParam.get("tbType").toString())) { // 独立文件
            Map<String, Object> m = recordManageMapper.selectRecordManageById(id, mapParam.get("tbName").toString());
            mapList.add(m);
        } else if ("1".equals(mapParam.get("tbType").toString())) { // 卷内文件
            Map<String, Object> mapSearch = new HashMap<>();
            mapSearch.put("archId", id);
            mapSearch.put("tbName", mapParam.get("tbName").toString());
            mapList = this.selectRecordManageList(mapSearch);
        } else {
            throw new GlobalException("查询文件数据异常！请联系管理员");
        }
        // 传入引用变量files，循环取出文件对象
        List<File> files = CollUtil.newArrayList();
        for (Map map : mapList) {
            this.getFiles(files, map);
        }

        //生成zip
        if (files.size() != 0) {
            String zipPath = RuoYiConfig.getZipPath() + "案卷包.zip";
            File[] zipfiles = ArrayUtil.toArray(files, File.class);

            File file = ZipUtil.zip(FileUtil.file(zipPath), false, zipfiles);
            //   System.out.println(fres.getAbsoluteFile());
            return file;
        }
        return null;
    }

    private void getFiles(List<File> files, Map<String, Object> map) {
        File f = null;
        String[] filepathArr = null;
        String[] imagespathArr = null;
        String filePath = null;
        // 文件存储对象
        if (map.get("filePath") != null && !"".equals(map.get("filePath").toString())) {
            filePath = map.get("filePath").toString();
            filepathArr = filePath.split(",");
            for (String s : filepathArr) {
                filePath = RuoYiConfig.getProfile() + File.separator + s.replace("/profile", "");
                f = new File(filePath);
                files.add(f);
            }
        }
        // 图片存储对象
        if (map.get("imagePath") != null && !"".equals(map.get("imagePath").toString())) {
            String imgpath = map.get("imagePath").toString();
            imagespathArr = imgpath.split(",");
            for (String s : imagespathArr) {
                filePath = RuoYiConfig.getProfile() + File.separator + s.replace("/profile", "");
                f = new File(filePath);
                files.add(f);
            }
        }
        // 表格存储对象
        List<Map<String, Object>> excellist = CollUtil.newArrayList();
        /* File excelFile = HutoolExcelUtiles.RecordFileExport(JSONArray.parseArray(JSONObject.toJSONString(list)));
           files.add(excelFile);*/
    }

    /***
     * 文件导入
     * @param
     * @return
     */
    @Override
    @Transactional
    public String importFile(List<Map<String, Object>> fileList, String tbName, String tbType) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        if (CollUtil.isEmpty(fileList)) {
            throw new ServiceException("导入文件数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (Map<String, Object> fileMap : fileList) {
            String title = null;
            try {
                BeanValidators.validateWithException(validator, fileMap);
                fileMap.put("tbName", tbName);
                fileMap.put("tbType", tbType);
                this.insertRecordManage(fileMap);
                if ("1".equals(tbType)) {
                    title = fileMap.get("acFileTitle").toString();
                } else {
                    title = fileMap.get("fileTitle").toString();
                }
                successNum++;
                successMsg.append("<br/>" + successNum + "、文件 " + title + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、文件 " + title + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
                //手工回滚异常
                TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            //手工回滚异常
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 查询档案
     *
     * @param id 档案  主键
     * @return 档案
     */
    @Override
    public Map<String, Object> selectRecordManageById(String id, String tbName) {
        return recordManageMapper.selectRecordManageById(id, tbName);
    }

    /**
     * 查询档案  列表
     *
     * @param map 档案
     * @return 档案
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<Map<String, Object>> selectRecordManageList(Map<String, Object> map) {
        if (map == null || map.size() == 0) {
            return null;
        }
        // 遍历取出
        Set<String> keySet = map.keySet();
        String propValue = " where 1=1 ";
        // 遍历keySet可以提出key的名称，key的值通过map.get(key)获取
        for (String key : keySet) {
            if (map.get(key) != null && this.filterKey(key)) {
                if ("id".equals(key) || "archId".equals(key) || "typeId".equals(key)) { // 属性为id时，不能模糊匹配
                    propValue = propValue + " and " + "a." + key + " = #{" + key + "}";
                } else if ("tag".equals(key)) {
                    propValue = propValue + " and " + " FIND_IN_SET( #{" + key + "} ,a." + key + " ) > 0";
                } else {
                    propValue = propValue + " and " + "a." + key + " like concat('%', #{" + key + "}, '%')";
                }
            }
        }
        String sql = "SELECT a.* FROM " + map.get("tbName") + " a"
                + " left join sys_user u on a.userId = u.user_id"
                + " left join sys_dept d on u.dept_id = d.dept_id"
                + propValue;
        map.put("sql", sql);
        return recordManageMapper.selectRecordManageList(map);
    }

    // 过滤key
    private boolean filterKey(String key) {
        if (!"tbName".equals(key)
                && !"isCustom".equals(key)
                && !"pageNum".equals(key)
                && !"pageSize".equals(key)
                && !"status".equals(key)
                && !"tbType".equals(key)
                && !"tableId".equals(key)
                && !"dataScope".equals(key)
                && !"tbNameArch".equals(key)
                && !"tbNameFile".equals(key)
        ) {
            return true;
        }
        return false;
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<Map<String, Object>> selectRecordManageListBook(Map<String, Object> map) {
        if (map == null || map.size() == 0) {
            return null;
        }
        //1.传入tbName1和tbName2，typeId获取案卷，卷内集合
        // 遍历取出
        Set<String> keySet = map.keySet();
        String propValue = " where 1=1 ";
        // 判断案卷或者文件查询，前端是分开输入参数的
        String schFlag = map.get("schFlag").toString();
        String t = null;
        if ("1".equals(schFlag)) {
            t = "a.";
        } else if ("2".equals(schFlag)) {
            t = "b.";
        }
        map.remove("schFlag");
        // 遍历keySet可以提出key的名称，key的值通过map.get(key)获取
        for (String key : keySet) {
            if (map.get(key) != null && this.filterKey(key)) {
                if ("typeId".equals(key)) { // 只有a表才有typeId
                    propValue = propValue + " and " + "a." + key + " = #{" + key + "}";
                } else if ("id".equals(key) || "archId".equals(key)) { // 属性为id时，不能模糊匹配
                    propValue = propValue + " and " + t + key + " = #{" + key + "}";
                } else {
                    propValue = propValue + " and " + t + key + " like concat('%', #{" + key + "}, '%')";
                }
            }
        }
        String sql = "SELECT * FROM " + map.get("tbNameArch") + " a"
                + " left join " + map.get("tbNameFile") + " b on a.id = b.archId"
                + " left join sys_user u on a.userId = u.user_id"
                + " left join sys_dept d on u.dept_id = d.dept_id"
                + propValue;
        map.put("sql", sql);
        return recordManageMapper.selectRecordManageList(map);
    }

    /**
     * 新增档案
     *
     * @param map 档案
     * @return 结果
     */
    @Override
    public Integer insertRecordManage(Map<String, Object> map) {
        // 验证挂载序号

        // 设置ID，用于自动生成
        map.put("id", "0");
        // 验证必填字段
        if ("1".equals(map.get("tbType").toString())) { // 案卷表
            if (StrUtil.isEmpty(map.get("typeId").toString())) {
                throw new GlobalException("档案分类ID不能空,请按规则填写");
            }
            if (ConfConstants.is_docNum.equals(sysConfigService.selectConfigByKey("is_docNum"))) {
                map.put("acDocNum", getDocNumArch(map));
            }
            map.put("acCreateBy", SecurityUtils.getUsername());
        } else if ("2".equals(map.get("tbType").toString())) { // 卷内表
            if (StrUtil.isEmpty(map.get("archId").toString())) {
                throw new GlobalException("案卷ID不能空,请按规则填写");
            }
            if (ConfConstants.is_docNum.equals(sysConfigService.selectConfigByKey("is_docNum"))) {
                map.put("docNum", getDocNumFile(map));
            }
            map.put("createBy", SecurityUtils.getUsername());
        } else if ("3".equals(map.get("tbType").toString())) { // 独立表
            if (StrUtil.isEmpty(map.get("typeId").toString())) {
                throw new GlobalException("档案分类ID不能空,请按规则填写");
            }
            if (ConfConstants.is_docNum.equals(sysConfigService.selectConfigByKey("is_docNum"))) {
                map.put("docNum", getDocNumFile(map));
            }
            map.put("createBy", SecurityUtils.getUsername());
        }
        map.put("userId", SecurityUtils.getUserId());
        map.put("createTime", DateUtils.getNowDate());

        if (map == null || map.size() == 0) {
            return null;
        }
        // 动态往数据库里新增数据
        Set<String> keySet = map.keySet();
        String prop = null;
        String value = null;
        int i = 0;
        // 遍历keySet可以提出key的名称，key的值通过map.get(key)获取
        for (String key : keySet) {
            if (map.get(key) != null && StringUtils.isNotEmpty(map.get(key).toString()) && this.filterKey(key)) {
                //传递tag
                StringBuffer sb = new StringBuffer();
                if (StringUtils.equals(key, "tag") && map.get(key) != null) {
                    List<String> list = (List<String>) map.get(key);
                    for (String s : list) {
                        sb.append(s).append(",");
                    }
                    if (sb.length() > 0) {
                        map.put(key, sb.substring(0, sb.lastIndexOf(",")));
                    }
                }
                if (i == 0) {
                    prop = key.trim();
                    value = "#{" + key.trim() + "}";
                } else {
                    prop = prop + ", " + key.trim();
                    value = value + ", #{" + key.trim() + "}";
                }
                i = i + 1;
            }
        }
        String sql = "INSERT INTO " + map.get("tbName") + " (" + prop + ") " + "VALUES" + " (" + value + ") ";
        map.put("sql", sql);
        return recordManageMapper.insertRecordManage(map);
    }

    private String getDocNumArch(Map<String, Object> map) {
        //档号生成规则   全宗号-分类号-年度-案卷号
        //全宗号
        String acFullAnces = (String) map.get("acFullAnces");
        if (StrUtil.isEmpty(acFullAnces)) {
            throw new GlobalException("全宗号不能空,请按规则填写");
        }
        //分类号
        String acCategoryNo = (String) map.get("acCategoryNo");
        if (StrUtil.isEmpty(acCategoryNo)) {
            throw new GlobalException("分类号不能空,请按规则填写");
        }
        //年度
        String acYear = (String) map.get("acYear");
        if (StrUtil.isEmpty(acYear)) {
            throw new GlobalException("年度不能空,请按规则填写");
        }
        //案卷号
        String acArchNum = (String) map.get("acArchNum");
        if (StrUtil.isEmpty(acArchNum)) {
            throw new GlobalException("案卷号不能空,请按规则填写");
        }
        StringBuilder stb = new StringBuilder();
        stb.append(acFullAnces).append("-");
        stb.append(acCategoryNo).append("-");
        stb.append(acYear).append("-");
        stb.append(acArchNum);
        return stb.toString();
    }

    private String getDocNumFile(Map<String, Object> map) {
        //档号生成规则   全宗号-分类号-年度-顺序号
        //全宗号
        String fullAnces = (String) map.get("fullAnces");
        if (StrUtil.isEmpty(fullAnces)) {
            throw new GlobalException("全宗号不能空,请按规则填写");
        }
        //分类号
        String categoryNo = (String) map.get("categoryNo");
        if (StrUtil.isEmpty(categoryNo)) {
            throw new GlobalException("分类号不能空,请按规则填写");
        }
        //年度
        String year = (String) map.get("year");
        if (StrUtil.isEmpty(year)) {
            throw new GlobalException("年度不能空,请按规则填写");
        }
        //顺序号
        String sequeNum = (String) map.get("sequeNum");
        if (StrUtil.isEmpty(sequeNum)) {
            throw new GlobalException("顺序号不能空,请按规则填写");
        }
        StringBuilder stb = new StringBuilder();
        stb.append(fullAnces).append("-");
        stb.append(categoryNo).append("-");
        stb.append(year).append("-");
        stb.append(sequeNum);
        return stb.toString();
    }

    /**
     * 修改档案
     *
     * @param map 档案
     * @return 结果
     */
    @Override
    public Integer updateRecordManage(Map<String, Object> map) {
        map.put("updateTime", DateUtils.getNowDate());
        map.put("updateBy", SecurityUtils.getUsername());

        if (map == null || map.size() == 0) {
            return null;
        }
        // 动态往数据库里新增数据
        Set<String> keySet = map.keySet();
        String propValue = null;
        int i = 0;
        // 遍历keySet可以提出key的名称，key的值通过map.get(key)获取
        List<String> ids = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keySet) {
            if (map.get(key) != null && this.filterKey(key)) {
                if (i == 0) {
                    ids = (List<String>) map.get(key);
//                    propValue = key + " = #{" + key + "}";
                } else {
                    propValue = propValue+", " + key + " = #{" + key + "}";
                }
                i = i + 1;
            }
        }
        for (String id : ids) {
            stringBuilder.append("'").append(id).append("'").append(",");
        }
        String id = "";
        if(stringBuilder.length() > 0)
        {
            id = stringBuilder.substring(0,stringBuilder.length() - 1).toString();
        }

        String sql = "UPDATE " + map.get("tbName") + " SET " + propValue.substring(6,propValue.length()) + " WHERE id in ("+id+")";
        map.put("sql", sql);
        return recordManageMapper.updateRecordManage(map);
    }

    /**
     * 批量删除档案
     *
     * @param ids 需要删除的档案  主键
     * @return 结果
     */
    @Override
    public Integer deleteRecordManageByIds(String[] ids, String tbName) {
        // 如果是档案表，先级联删除卷内表。否则直接删除
        try {
            RecordTable r1 = new RecordTable();
            r1.setTbName(tbName);
            RecordTable tbNew1 = recordTableMapper.selectRecordTableList(r1).get(0);
            if ("1".equals(tbNew1.getTbType())) { // 1是案卷档案
                // 获取卷内表表名
                RecordTable r2 = new RecordTable();
                r2.setTypeId(tbNew1.getTypeId());
                r2.setTbType("2");
                RecordTable tbNew2 = recordTableMapper.selectRecordTableList(r2).get(0);
                String tbNameFile = tbNew2.getTbName();
                for (String archId : ids) {
                    Map<String, Object> map = new HashMap<>();
                    String sql = "delete from " + tbNameFile + " where archId = " + archId;
                    map.put("sql", sql);
                    recordManageMapper.deleteRecordManage(map);
                }
                recordManageMapper.deleteRecordManageByIds(ids, tbName);
            } else {
                recordManageMapper.deleteRecordManageByIds(ids, tbName);
            }
            return 1;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 批量文件上传 独立文件
     *
     * @param
     * @return 结果
     */
    @Override
    @Transactional
    public String upLoadMultFile(Map<String, Object> map_c) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        int successNum = 0;
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder message = new StringBuilder();
        String tbName = map_c.get("tbName").toString();
        try {
            String fp = map_c.get("filePath").toString();
            String[] strs = fp.split(",");
            for (int i = 0; i < strs.length; i++) {
                String path = strs[i];
                // 截取最后一次出现.号和最后一个出现-号的字符。比如xxx-001.pdf,截取的是001，对应的是挂载序号
                String mountNum = strs[i].substring(strs[i].lastIndexOf("-") + 1, strs[i].lastIndexOf("."));
                String fileName = strs[i].substring(strs[i].lastIndexOf("-") + 1);
                // 判断是否存在挂载序号
                List<Map<String, Object>> mapList = new ArrayList();
                if ("2".equals(map_c.get("tbType").toString())) { // 卷内文件
                    mapList = recordManageMapper.getMultByArchId(mountNum, tbName, map_c.get("archId").toString());
                } else if ("3".equals(map_c.get("tbType").toString())) { // 独立文件
                    mapList = recordManageMapper.getMultByTypeId(mountNum, tbName, map_c.get("typeId").toString());
                }
                if (mapList.size() > 1) {
                    throw new ServiceException("挂载失败，请确保挂载序号唯一");
                } else if (mapList.size() == 0) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、文件 " + fileName + " 挂载序号不匹配");
                    log.error(failureNum + "、文件 " + fileName + " 挂载序号不匹配");
                } else if (mapList.size() == 1) {
                    Map<String, Object> map = mapList.get(0);
                    // 存在挂载序号，且数据库里面filePath不为空，往后添加。存在挂载序号，filePath为空，直接挂载。否则提示挂载失败信息。
                    if (map.get("filePath") != null && !"".equals(map.get("filePath").toString())) {
                        map.put("tbName", tbName);
                        String paths = map.get("filePath").toString() + "," + path;
                        map.put("filePath", paths);
                        this.updateRecordManage(map);
                        successNum++;
                    } else {
                        map.put("tbName", tbName);
                        map.put("filePath", path);
                        this.updateRecordManage(map);
                        successNum++;
                    }
                }
            }
            int fNum = strs.length; // 文件数
            int dNum = 0; // 数据量
            if ("2".equals(map_c.get("tbType").toString())) { // 卷内文件
                dNum = recordManageMapper.getMultByArchId(null, tbName, map_c.get("archId").toString()).size();
            } else if ("3".equals(map_c.get("tbType").toString())) { // 独立文件
                dNum = recordManageMapper.getMultByTypeId(null, tbName, map_c.get("typeId").toString()).size();
            }
            message.append("<br/>" + "失败数据如下：" + failureMsg);
            message.insert(0, "上传校验：上传文件数" + fNum + "，" + "系统数据量" + dNum + "。" + "<br/>" + "上传情况：成功" + successNum + "，失败" + failureNum + "。");
            return message.toString();
        } catch (Exception e) {
            //手工回滚异常
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            throw new RuntimeException(e);
        }
    }

    @Override
    @Transactional
    public Integer updateArchivesApplyByIds(String[] ids, String tbName, String tbType) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            for (String id : ids) {
                Map<String, Object> map = new HashMap<>();
                map.put("tbName", tbName);
                map.put("id", id);
                map.put("archStatus", "1"); //申请状态字段，1：申请
                Map<String, Object> oldMap = this.selectRecordManageById(id, tbName);
                if ("0".equals(oldMap.get("archStatus")) || "3".equals(oldMap.get("archStatus"))) { // 未申请或拒绝状态，可申请
                    // 更新案卷归档状态
                    int res = this.updateRecordManage(map);
                    // 如果是案卷卷内，更新卷内归档状态
                    if ("1".equals(tbType)) {
                        this.updateFileStatus(id, tbName, "1");
                    }
                    if (res != 1) { // 更新条数为0
                        //手工回滚异常
                        TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                        throw new ServiceException("操作失败！数据更新条数为0");
                    }
                } else {
                    //手工回滚异常
                    TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                    throw new ServiceException("只允许操作未申请和审批拒绝的案卷");
                }
            }
        } catch (TransactionException e) {
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            e.printStackTrace();
        }
        return 1;
    }

    @Override
    @Transactional
    public Integer updateArchivesApprove(String[] ids, String tbName, String tbType) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            for (String id : ids) {
                Map<String, Object> map = new HashMap<>();
                map.put("tbName", tbName);
                map.put("id", id);
                map.put("archStatus", "2"); //申请状态字段，2：通过
                Map<String, Object> oldMap = this.selectRecordManageById(id, tbName);
                if ("1".equals(oldMap.get("archStatus"))) { // 申请中状态，可审批
                    // 更新案卷归档状态
                    int res = this.updateRecordManage(map);
                    // 如果是案卷，更新卷内归档状态
                    if ("1".equals(tbType)) {
                        this.updateFileStatus(id, tbName, "2");
                    }
                    if (res != 1) { // 更新条数为0
                        //手工回滚异常
                        TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                        throw new ServiceException("操作失败！数据更新条数为0");
                    }
                } else {
                    //手工回滚异常
                    TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                    throw new ServiceException("只允许操作申请中的案卷");
                }
            }
        } catch (TransactionException e) {
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            e.printStackTrace();
        }
        return 1;
    }

    @Override
    @Transactional
    public Integer updateArchivesReject(String[] ids, String tbName, String tbType) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        try {
            for (String id : ids) {
                Map<String, Object> map = new HashMap<>();
                map.put("tbName", tbName);
                map.put("id", id);
                map.put("archStatus", "3"); //申请状态字段，3：拒绝
                Map<String, Object> oldMap = this.selectRecordManageById(id, tbName);
                if ("1".equals(oldMap.get("archStatus"))) { // 申请中状态，可审批
                    // 更新案卷归档状态
                    int res = this.updateRecordManage(map);
                    // 如果是案卷卷内，更新卷内归档状态
                    if ("1".equals(tbType)) {
                        this.updateFileStatus(id, tbName, "3");
                    }
                    if (res != 1) { // 更新条数为0
                        //手工回滚异常
                        TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                        throw new ServiceException("操作失败！数据更新条数为0");
                    }
                } else {
                    //手工回滚异常
                    TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
                    throw new ServiceException("只允许操作申请中的案卷");
                }
            }
        } catch (TransactionException e) {
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            e.printStackTrace();
        }
        return 1;
    }

    // 更改卷内归档状态
    private void updateFileStatus(String archId, String tbNameArch, String archStatus) {
        // 根据tbName查询出typeId
        // 根据typeId和tbType查询出卷内tbName
        // 根据archId, tbName, archStatus 批量修改卷内归档状态
        RecordTable r1 = new RecordTable();
        r1.setTbName(tbNameArch);
        String typeId = recordTableMapper.selectRecordTableList(r1).get(0).getTypeId();
        RecordTable r2 = new RecordTable();
        r2.setTypeId(typeId);
        r2.setTbType("2");
        String tbName = recordTableMapper.selectRecordTableList(r2).get(0).getTbName();

        Map<String, Object> map = new HashMap<>();
        map.put("archId", archId);
        String sql = "UPDATE " + tbName + " SET archStatus = " + archStatus + " WHERE archId = #{archId}";
        map.put("sql", sql);
        recordManageMapper.updateRecordManage(map);
    }

}
